package com.tsfyun.scm.service.impl.materiel;

import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.enums.MaterielBrandTypeEnum;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.extension.OrderItem;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.dto.materiel.MaterielBrandDTO;
import com.tsfyun.scm.dto.materiel.MaterielBrandQTO;
import com.tsfyun.scm.entity.materiel.MaterielBrand;
import com.tsfyun.scm.mapper.materiel.MaterielBrandMapper;
import com.tsfyun.scm.service.materiel.IMaterielBrandService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.util.TsfWeekendSqls;
import com.tsfyun.scm.vo.materiel.MaterielBrandVO;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 物料品牌 服务实现类
 * </p>
 *

 * @since 2020-03-26
 */
@Service
public class MaterielBrandServiceImpl extends ServiceImpl<MaterielBrand> implements IMaterielBrandService {

    @Autowired
    private MaterielBrandMapper materielBrandMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(MaterielBrandDTO dto) {
        dto.setName(StringUtils.null2EmptyWithTrim(dto.getName()).toUpperCase());
        MaterielBrand materielBrand = beanMapper.map(dto,MaterielBrand.class);
        try {
            materielBrand.setId(StringUtils.uuid());
            super.saveNonNull(materielBrand);
        } catch (DuplicateKeyException e) {
            if(e.getMessage().contains("UK_materiel_brand_name")) {
                throw new ServiceException("英文名称已经存在");
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(MaterielBrandDTO dto) {
        dto.setName(StringUtils.null2EmptyWithTrim(dto.getName()).toUpperCase());
        MaterielBrand materielBrand = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(materielBrand),new ServiceException("数据不存在"));
        materielBrand.setType(dto.getType());
        materielBrand.setName(dto.getName());
        materielBrand.setMemo(dto.getMemo());
        try {
            super.updateById(materielBrand);
        } catch (DuplicateKeyException e) {
            if(e.getMessage().contains("UK_materiel_brand_name")) {
                throw new ServiceException("英文名称已经存在");
            }
        }
    }

    @Override
    public PageInfo<MaterielBrand> pageList(MaterielBrandQTO dto) {
        TsfWeekendSqls wheres = TsfWeekendSqls.<MaterielBrand>custom()
                .andLike(true,MaterielBrand::getName,dto.getName())
                .andLike(true,MaterielBrand::getMemo,dto.getMemo())
                .andEqualTo(true,MaterielBrand::getType,dto.getType());
        return super.pageList(dto.getPage(),dto.getLimit(),wheres, Lists.newArrayList(OrderItem.asc("name")));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        MaterielBrand materielBrand = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(materielBrand),new ServiceException("数据不存在"));
        try {
            super.removeById(id);
        } catch (DataIntegrityViolationException e) {
            throw new ServiceException("当前物料品牌存在关联性数据，不允许删除");
        }
    }

    @Override
    public MaterielBrandVO detail(String id) {
        MaterielBrand materielBrand = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(materielBrand),new ServiceException("数据不存在"));
        return beanMapper.map(materielBrand,MaterielBrandVO.class);
    }

    @Override
    public MaterielBrandVO findByName(String name) {
        if(StringUtils.isEmpty(name)) {
            return null;
        }
        MaterielBrand materielBrand = new MaterielBrand();
        materielBrand.setName(name);
        materielBrand = super.getOne(materielBrand);
        if(Objects.isNull(materielBrand)) {
            return null;
        }
        return beanMapper.map(materielBrand,MaterielBrandVO.class);
    }

    @Override
    public List<MaterielBrandVO> findByNames(String... names) {
        if(ArrayUtils.isEmpty(names)) {
            return null;
        }
        List<MaterielBrand> materielBrands =  materielBrandMapper.selectByExample(Example.builder(MaterielBrand.class).where(TsfWeekendSqls.<MaterielBrand>custom().andIn(false,MaterielBrand::getName, Arrays.asList(names))).build());
        return beanMapper.mapAsList(materielBrands,MaterielBrandVO.class);
    }

    @Override
    public List<MaterielBrandVO> select(String name) {
        MaterielBrandQTO qto = new MaterielBrandQTO();
        qto.setPage(1);
        qto.setLimit(20);
        qto.setName(name);
        PageInfo<MaterielBrand> pageInfo = pageList(qto);
        return beanMapper.mapAsList(pageInfo.getList(),MaterielBrandVO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveMaterielBrand(MaterielBrand mb) {
        //校验品牌类型是否错误如果不为空的话
        if(StringUtils.isNotEmpty(mb.getType()) && Objects.isNull(MaterielBrandTypeEnum.of(mb.getType()))) {
            throw new ServiceException("品牌类型错误");
        }
        mb.setId(StringUtils.UUID());
        if(StringUtils.isEmpty(mb.getMemo())){
            mb.setMemo("无");
        }
        materielBrandMapper.insertOrUpdate(mb);
    }

    @Override
    public String findZhByNameEn(String name) {
        MaterielBrandVO vo = findByName(name);
        if(Objects.nonNull(vo)){
            return vo.getMemo();
        }
        return "";
    }
}
